package la.iok.hzsvn.lewin.movie.shopmovie.service;

import la.iok.hzsvn.lewin.movie.core.Token;
import la.iok.hzsvn.lewin.movie.core.shopmovie.param.CouponBaseFilterParam;
import la.iok.hzsvn.lewin.movie.core.shopmovie.param.CouponListParam;
import la.iok.hzsvn.lewin.movie.core.shopmovie.param.CouponParam;
import la.iok.hzsvn.lewin.movie.core.shopmovie.vo.CouponVo;
import la.iok.hzsvn.lewin.movie.shopmovie.entity.Coupon;
import la.iok.hzsvn.lewin.movie.shopmovie.model.CouponQRInfo;
import la.iok.hzsvn.lewin.movie.shopmovie.model.EfficacyCouponVo;
import la.iok.hzsvn.lewin.mybatis.model.PageParam;
import la.iok.hzsvn.lewin.mybatis.model.PageVo;
import la.iok.hzsvn.lewin.mybatis.model.SortParam;
import la.iok.hzsvn.lewin.mybatis.service.BaseService;
import la.iok.hzsvn.share.annotations.NotNull;
import la.iok.hzsvn.share.annotations.NotNullElement;
import la.iok.hzsvn.share.annotations.Nullable;

import java.util.List;

public interface CouponService extends BaseService<Coupon, Long> {
    /**
     * 管理员发放优惠券给用户
     * @param token 操作用户
     * @param userId 用户id
     * @param param 优惠券参数
     * @return 新创建优惠券id
     */
    Long grant(@NotNull Token token, @Nullable Long userId, @NotNull CouponParam param);

    /**
     * 创建优惠券并返回创建的优惠券id。之后可以查询优惠券并生成二维码供用户扫描
     * @param token 操作用户
     * @param param 优惠券参数
     * @return 新创建优惠券id
     */
    CouponQRInfo create(@NotNull Token token, @NotNull CouponParam param);
    /**
     * 用户扫描优惠券二维码获取优惠券
     * @param token 用户令牌
     * @param uuid 二维码uuid
     */
    void take(@NotNull Token token, @NotNull String uuid);

    /**
     * 生成二维码的唯一id.以12位的时间戳（秒计，可以表示0到4095秒范围（68分钟），这个就是id的最大有效时长）,
     * 19位做秒内的并发数（0-524287范围，超过50万）。共31位，最高位为0，每秒50万并发数。
     * 生成的整数以十六进制格式化
     * @return 二维码id
     */
    String qrcodeId();

    /**
     * 分页查询优惠券。查询自己拥有的或者自己所在组织派发的优惠券
     * @param token 操作用户令牌
     * @param pageParam 分页参数
     * @param sortParam 排序参数
     * @param listParam 列表参数
     * @return 分页数据
     */
    PageVo<CouponVo> page(@NotNull Token token, @NotNull PageParam pageParam, @NotNull SortParam sortParam, @NotNull CouponListParam listParam);

    /**
     * 使用优惠券。将优惠券状态设置为已使用
     * @param coupon 优惠券对象
     * @return 受影响记录数。正常应该为1，非1代表操作失败
     */
    int use(@NotNull Coupon coupon);

    int waitLock(@NotNull Coupon coupon);

    int unWaitLock(@NotNull Coupon coupon);

    int lock(@NotNull Coupon coupon);

    int unLock(@NotNull Coupon coupon);
    /**
     * 删除优惠券。只能删除未被领取的优惠券
     * @param token 操作用户
     * @param id 优惠券id
     */
    void delete(Token token, Long id);





    /**
     * 查询优惠券信息
     * @param token 操作用户
     * @param id 优惠券id
     * @return 优惠券信息
     */
    @Nullable
    CouponVo select(@NotNull Token token, @NotNull Long id);

    /**
     * 查询二维码对应的优惠券信息
     * @param token 操作用户
     * @param uuid 二维码id
     * @return 优惠券信息
     */
    @Nullable
    CouponVo select(@NotNull Token token, @NotNull String uuid);

    /**
     * 删除优惠券定义
     * @param token 操作用户
     * @param couponDefId 优惠券定义id
     */
    void deleteDefinition(Token token, Long couponDefId);

    /***
     * 查询用户可使用优惠券
     * @param token 用户令牌
     * @param param 过滤参数
     * @return 优惠券列表
     */
    @NotNull
    @NotNullElement
    List<CouponVo> usable(@NotNull Token token, @NotNull CouponBaseFilterParam param);


    PageVo<EfficacyCouponVo>efficacypage(@NotNull Token token, @NotNull PageParam pageParam, @NotNull SortParam sortParam, @NotNull Long dayNum);

}
